#include "modbus_device_uart.h"
#include "stm32_uart.h"
#include "app_netxduo.h"


/********************************** define **************************************/
static int32_t device_init(void *handle);
static int32_t device_send_data_rtu(void *com_handle, uint8_t *data, uint16_t length);
static int32_t device_send_data_tcp(void *com_handle, uint8_t *data, uint16_t length);
static int32_t device_read_discrete_bit(uint16_t bit_addr, uint8_t *bit_data, uint16_t bit_count);
static int32_t device_read_input_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t device_read_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t device_write_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count);
static int32_t device_read_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len);
static int32_t device_write_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len);


static MODBUS_Data_Buffer_t tx_buffer_rtu = 
{
  UART7_Transfer.TxData,
  &UART7_Transfer.RxData_Len,
  (int32_t *)&UART7_Transfer.Transfer_TX_Status,
};

static MODBUS_Data_Buffer_t rx_buffer_rtu = 
{
  UART7_Transfer.RxData,
  &UART7_Transfer.RxData_Len,
  (int32_t *)&UART7_Transfer.Transfer_RX_Status,
};

static MODBUS_Data_Buffer_t tx_buffer_tcp = 
{
  nx_tx_data.data,
  (uint16_t *)&nx_tx_data.length,
  (int32_t *)&nx_tx_data.status,
};

static MODBUS_Data_Buffer_t rx_buffer_tcp = 
{
  nx_rx_data.data,
  (uint16_t *)&nx_rx_data.length,
  (int32_t *)&nx_rx_data.status,
};

static MODBUS_Bit_Count_t discrete_bit;
static MODBUS_Reg_Count_t input_reg;
static MODBUS_Reg_Count_t hold_reg;

static uint16_t socket_reg_start_addr = 0x0000;
static uint16_t socket_reg_count = 0x4000;

static uint16_t socket_bit_start_addr = 0x0000;
static uint16_t socket_bit_count = 0x4000;

static uint8_t device_id = 0x01;

uint8_t modbus_d0_buff[0x4000 * 2];

MODBUS_User_Reg_t modbus_device_uart = 
{
  &modbus_device_uart,
  device_init,
};


static int32_t device_init(void *handle)
{
  MODBUS_User_Reg_t *device_handle = (MODBUS_User_Reg_t *)handle;
  
  device_handle->read_discrete_bit = device_read_discrete_bit;
  device_handle->read_input_reg = device_read_input_reg;
  device_handle->read_hold_reg = device_read_hold_reg;
  device_handle->write_hold_reg = device_write_hold_reg;
  device_handle->read_user_file = device_read_file;
  device_handle->write_user_file = device_write_file;

  device_handle->send_rtu = device_send_data_rtu;
  device_handle->send_rtu_com = &huart7;
  device_handle->tx_buffer_rtu = &tx_buffer_rtu;
  device_handle->rx_buffer_rtu = &rx_buffer_rtu;
  
  device_handle->send_tcp = device_send_data_tcp;
  device_handle->send_tcp_com = NULL;
  device_handle->tx_buffer_tcp = &tx_buffer_tcp;
  device_handle->rx_buffer_tcp = &rx_buffer_tcp;
  
  device_handle->modbus_device_id = &device_id;

  discrete_bit.start_addr = &socket_bit_start_addr;
  discrete_bit.count = &socket_bit_count;
  device_handle->discrete_bit = &discrete_bit;
  
  input_reg.start_addr = &socket_reg_start_addr;
  input_reg.count = &socket_reg_count;
  device_handle->input_reg = &input_reg;
  
  hold_reg.start_addr = &socket_reg_start_addr;
  hold_reg.count = &socket_reg_count;
  device_handle->hold_reg = &hold_reg;
  
  return 0;
}


static int32_t device_send_data_rtu(void *com_handle, uint8_t *data, uint16_t length)
{
  uint32_t ret;
  HAL_GPIO_WritePin(UART7_DE_GPIO_Port, UART7_DE_Pin, GPIO_PIN_SET);
  ret = STM32_UART_TransmitData_DMA(com_handle, data, length);
//  HAL_GPIO_WritePin(UART7_DE_GPIO_Port, UART7_DE_Pin, GPIO_PIN_RESET);
  return ret;
}

static int32_t device_send_data_tcp(void *com_handle, uint8_t *data, uint16_t length)
{
  int32_t ret;
  
  ret = nx_packet_allocate(&NxAppPool, &nx_tx_data.packet, NX_TCP_PACKET, NX_NO_WAIT);
        
  ret = nx_packet_data_append(nx_tx_data.packet, (VOID *)data, length, &NxAppPool, NX_NO_WAIT);

  ret = nx_tcp_socket_send(com_handle, nx_tx_data.packet, NX_NO_WAIT);
  
  return ret;
}


static int32_t device_read_discrete_bit(uint16_t bit_addr, uint8_t *bit_data, uint16_t bit_count)
{
  return 0;
}


/**
  * @brief  读输入寄存器(用户代码)
  * @note   1个寄存器占2Byte
  * @param  reg_addr: 寄存器地址
  * @param  reg_data: 寄存器数据
  * @param  reg_count: 寄存器数量
  * @retval 0
  */
static int32_t device_read_input_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  switch (reg_addr)
  {
    case 0x0020:
      modbus_d0_buff[0x0020*2+0] = 0x41;
      modbus_d0_buff[0x0020*2+1] = 0x42;
      modbus_d0_buff[0x0020*2+2] = 0x43;
      modbus_d0_buff[0x0020*2+3] = 0x44;
      modbus_d0_buff[0x0020*2+4] = 0x45;
      modbus_d0_buff[0x0020*2+5] = 0x46;
      modbus_d0_buff[0x0020*2+6] = 0x47;
      modbus_d0_buff[0x0020*2+7] = 0x48;
      break;
    
    default:
      break;
  }
  
  memcpy(reg_data, (modbus_d0_buff + reg_addr * 2), reg_count * 2);
  
  return 0;
}


/**
  * @brief  读保持寄存器(用户代码)
  * @note   1个寄存器占2Byte
  * @param  reg_addr: 寄存器地址
  * @param  reg_data: 寄存器数据
  * @param  reg_count: 寄存器数量
  * @retval 0
  */
static int32_t device_read_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  switch (reg_addr)
  {
    case 0x0000:
      modbus_d0_buff[0x0000*2+0] = 0x31;
      modbus_d0_buff[0x0000*2+1] = 0x32;
      modbus_d0_buff[0x0000*2+2] = 0x33;
      modbus_d0_buff[0x0000*2+3] = 0x34;
      modbus_d0_buff[0x0000*2+4] = 0x35;
      modbus_d0_buff[0x0000*2+5] = 0x36;
      modbus_d0_buff[0x0000*2+6] = 0x37;
      modbus_d0_buff[0x0000*2+7] = 0x38;
      break;
    
    default:
      break;
  }
  
  memcpy(reg_data, (modbus_d0_buff + reg_addr * 2), reg_count * 2);
  
  return 0;
}


/**
  * @brief  写保持寄存器(用户代码)
  * @note   1个寄存器占2Byte
  * @param  reg_addr: 寄存器地址
  * @param  reg_data: 寄存器数据
  * @param  reg_count: 寄存器数量
  * @retval 0
  */
static int32_t device_write_hold_reg(uint16_t reg_addr, uint8_t *reg_data, uint8_t reg_count)
{
  int32_t res = MODBUS_SUCCEED;
  switch (reg_addr)
  {
    case 0x0000:
      break;
    
    case 0x0001:
      break;
    
    default:
      break;
  }
  
  memcpy((modbus_d0_buff + reg_addr * 2), reg_data, reg_count * 2);
  
  return res;
}



static int32_t device_read_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len)
{ 
  return 0;
}


static int32_t device_write_file(uint16_t file, uint32_t pack_num, uint8_t *data, uint16_t pack_len)
{
  return 0;
}






